package config

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
	"os"
	"smyx.com/gwt/global"
	"smyx.com/gwt/utils"
	"time"
)

var (
	level   zapcore.Level
	options []zap.Option
)

// InitializeLog 初始化日志信息
func InitializeLog() *zap.Logger {
	if ok, _ := utils.PathExists(global.GApp.Config.Log.RootDir); !ok {
		_ = os.Mkdir(global.GApp.Config.Log.RootDir, os.ModePerm)
	}
	setLogLevel()
	if global.GApp.Config.Log.ShowLine {
		options = append(options, zap.AddCaller())
	}
	// 创建多个 WriteSyncer，一个写入文件，一个写入控制台
	fileWriter := getLogWriter()
	consoleWriter := zapcore.Lock(os.Stdout)
	writeSyncer := zapcore.NewMultiWriteSyncer(fileWriter, consoleWriter)
	// 设置编码器
	encoder := getZapEncoder()
	// 创建 Core
	core := zapcore.NewCore(encoder, writeSyncer, level)
	return zap.New(core, options...)
}

func setLogLevel() {
	switch global.GApp.Config.Log.Level {
	case "debug":
		level = zap.DebugLevel
		options = append(options, zap.AddStacktrace(level))
	case "info":
		level = zap.InfoLevel
	case "warn":
		level = zap.WarnLevel
	case "error":
		level = zap.ErrorLevel
		options = append(options, zap.AddStacktrace(level))
	case "dpanic":
		level = zap.DPanicLevel
	case "panic":
		level = zap.PanicLevel
	case "fatal":
		level = zap.FatalLevel
	default:
		level = zap.InfoLevel
	}
}

// 获取编码器
func getZapEncoder() zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = func(time time.Time, encoder zapcore.PrimitiveArrayEncoder) {
		encoder.AppendString(time.Format("[" + "2006-01-02 15:04:05.000" + "]"))
	}
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	if global.GApp.Config.Log.Format == "json" {
		return zapcore.NewJSONEncoder(encoderConfig)
	}
	return zapcore.NewConsoleEncoder(encoderConfig)
}

// 使用 lumberjack 作为日志写入器
func getLogWriter() zapcore.WriteSyncer {
	file := &lumberjack.Logger{
		Filename:   global.GApp.Config.Log.RootDir + "/" + global.GApp.Config.Log.Filename,
		MaxSize:    global.GApp.Config.Log.MaxSize,
		MaxBackups: global.GApp.Config.Log.MaxBackups,
		MaxAge:     global.GApp.Config.Log.MaxAge,
		Compress:   global.GApp.Config.Log.Compress,
	}
	return zapcore.AddSync(file)
}
